/*
 * Copyright 2016 Kejun Xia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.shipdream.lib.ohos.mvc.view.injection;


import com.shipdream.lib.ohos.mvc.*;
import com.shipdream.lib.ohos.mvc.view.help.LifeCycleMonitor;
import com.shipdream.lib.ohos.mvc.view.injection.controller.ControllerA;
import com.shipdream.lib.ohos.mvc.view.injection.controller.ControllerB;
import com.shipdream.lib.ohos.mvc.view.injection.controller.ControllerC;
import com.shipdream.lib.ohos.mvc.view.injection.controller.ControllerD;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.utils.PacMap;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import javax.inject.Inject;

public abstract class FragmentInjection<C extends FragmentController> extends MvcFragment<C> {
    private Button buttonGo;
    private Text title;
    protected Text textViewA;
    protected Text textViewB;
    protected Text textViewC;
    protected Text spinnerText;
    private int position;
    private List<String> listArray;

    @Inject
    private NavigationManager navigationManager;

    @Override
    protected int getLayoutResId() {
        return ResourceTable.Layout_fragment_injection;
    }

    @Override
    public void onViewReady(Component view, PacMap savedInstanceState, Reason reason) {
        getLifeCycleMonitor().onCreateView(view, savedInstanceState);
        getLifeCycleMonitor().onViewCreated(view, savedInstanceState);
        super.onViewReady(view, savedInstanceState, reason);
        getLifeCycleMonitor().onViewReady(view, savedInstanceState, reason);
        String[] stringArray = getFractionAbility().getStringArray(ResourceTable.Strarray_injection_test_locations);
        listArray = Arrays.asList(stringArray);
        buttonGo = (Button) view.findComponentById(ResourceTable.Id_buttonGo);
        title = (Text) view.findComponentById(ResourceTable.Id_title);
        textViewA = (Text) view.findComponentById(ResourceTable.Id_textA);
        textViewB = (Text) view.findComponentById(ResourceTable.Id_textB);
        textViewC = (Text) view.findComponentById(ResourceTable.Id_textC);
        spinnerText = (Text) view.findComponentById(ResourceTable.Id_spinner_text);
        Component spinner = view.findComponentById(ResourceTable.Id_spinner);
        spinner.setClickedListener(component -> setSpinner(view));

        buttonGo.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                Class loc = null;
                String item = listArray.get(position);
                if (item.equals("A")) {
                    loc = ControllerA.class;
                } else if (item.equals("B")) {
                    loc = ControllerB.class;
                } else if (item.equals("C")) {
                    loc = ControllerC.class;
                } else if (item.equals("D")) {
                    loc = ControllerD.class;
                }
                navigationManager.navigate(view).to(loc);
            }
        });

        setUpData();

        title.setText("Loc:" + printHistory());

    }

    private void setSpinner(Component view) {
        SpinnerAdapter spanAdapter = new SpinnerAdapter(listArray);
        CommonDialog commonDialog = new CommonDialog(getFractionAbility());
        commonDialog.setSize(vp2px(50), vp2px(80));
        commonDialog.setOffset(vp2px(15), vp2px(90));
        commonDialog.setAlignment(LayoutAlignment.TOP | LayoutAlignment.LEFT);
        commonDialog.setAutoClosable(true);
        ListContainer listContainer = new ListContainer(getFractionAbility());
        ComponentContainer.LayoutConfig layoutConfig = new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
        listContainer.setLayoutConfig(layoutConfig);
        ShapeElement shapeElement = new ShapeElement(getFractionAbility(), ResourceTable.Graphic_background_list_apinner);
        listContainer.setBackground(shapeElement);
        commonDialog.setContentCustomComponent(listContainer);
        listContainer.setItemProvider(spanAdapter);
        spinnerText.setText(listArray.get(0));
        listContainer.setItemClickedListener((listContainer1, component, position, ll) -> {
            this.position = position;
            String item = listArray.get(position);
            spinnerText.setText(item);
            commonDialog.destroy();
        });
        commonDialog.show();
        Optional<WindowManager.LayoutConfig> configOpt = commonDialog.getWindow().getLayoutConfig();
        configOpt.ifPresent(config -> {
            config.dim = 0.0f;
            commonDialog.getWindow().setLayoutConfig(config);
        });
    }

    private int vp2px(float vp) {
        Display display = DisplayManager.getInstance().getDefaultDisplay(getFractionAbility()).get();
        float dpi = display.getAttributes().densityPixels;
        return (int) (vp * dpi + 0.5d * (vp >= 0 ? 1 : -1));
    }

    @Override
    public void onResume() {
        super.onResume();
        getLifeCycleMonitor().onResume();
    }

    private String printHistory() {
        NavLocation curLoc = navigationManager.getModel().getCurrentLocation();
        String history = getLocName(curLoc);
        while (curLoc != null) {
            if (curLoc.getPreviousLocation() != null) {
                history = getLocName(curLoc.getPreviousLocation()) + "-> " + history;
            }
            curLoc = curLoc.getPreviousLocation();
        }
        return history;
    }

    private String getLocName(NavLocation navLocation) {
        if (navLocation == null) {
            return "";
        } else {
            String id = navLocation.getLocationId();
            return id.substring(id.length() - 1);
        }
    }

    protected void displayTags(Text textView, List<String> tags) {
        StringBuilder str = new StringBuilder();
        for (String s : tags) {
            if (str.length() > 0) {
                str.append("\n");
            }
            str.append(s);
        }
        textView.setText(str.toString());
    }

    protected abstract void setUpData();

    protected abstract LifeCycleMonitor getLifeCycleMonitor();

    @Override
    protected void onCreate(PacMap savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLifeCycleMonitor().onCreate(savedInstanceState);

        Log.d("MvcTesting", "onCreated " + getClass().getSimpleName());
    }

    @Override
    protected void onReturnForeground() {
        super.onReturnForeground();
        getLifeCycleMonitor().onReturnForeground();
    }

    @Override
    protected void onPushToBackStack() {
        super.onPushToBackStack();
        getLifeCycleMonitor().onPushToBackStack();
    }

    @Override
    protected void onPopAway() {
        super.onPopAway();
        getLifeCycleMonitor().onPopAway();
    }

    @Override
    protected void onPoppedOutToFront() {
        super.onPoppedOutToFront();
        getLifeCycleMonitor().onPoppedOutToFront();
    }

    @Override
    protected void onOrientationChanged(int lastOrientation, int currentOrientation) {
        super.onOrientationChanged(lastOrientation, currentOrientation);
        getLifeCycleMonitor().onOrientationChanged(lastOrientation, currentOrientation);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        getLifeCycleMonitor().onDestroyView();
    }

    @Override
    public void onDestroy() {
        getLifeCycleMonitor().onDestroy();
        super.onDestroy();
    }

    class SpinnerAdapter extends BaseItemProvider {

        private List<String> list;

        public SpinnerAdapter(List<String> list) {
            this.list = list;
        }

        @Override
        public int getCount() {
            return list != null ? list.size() : 0;
        }

        @Override
        public Object getItem(int pos) {
            return list != null ? list.get(pos) : null;
        }

        @Override
        public long getItemId(int pos) {
            return pos;
        }

        @Override
        public Component getComponent(int pos, Component component, ComponentContainer componentContainer) {
            ViewHolder viewHolder = null;
            if (component == null) {
                component = LayoutScatter.getInstance(getFractionAbility()).parse(ResourceTable.Layout_spinner_item, null, false);
                viewHolder = new ViewHolder(component);
                component.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) component.getTag();
            }
            viewHolder.spanText.setText(list.get(pos));

            return component;
        }
    }

    class ViewHolder {
        Text spanText;

        public ViewHolder(Component component) {
            this.spanText = (Text) component.findComponentById(ResourceTable.Id_text_item);
        }
    }

}
